package finman.database;
import java.util.*;

/**
 * Encapsulate information about bank. Contain its name and
 * set of open accounts that user can open in this bank.
 */
public class Bank {
	private String name;
	private Set<Schet> scheta = new HashSet<Schet>();

    /**
     * Creates empty bank (without any accounts) with specified name.
     */
	public Bank(String name) {
		this.name = name;		
	}
	
	/**
	 * Opens new account: Obtains unique account number by getFreeAccountNumber(), then
     * creates account object and adds its to set of accounts in this bank.
     * @return the number of new account.
	 */
	public String openAccount(Valuta valuta, Double initialBalance) {		
		Schet newSchet = new Schet(getFreeAccountNumber(), valuta, initialBalance);
		scheta.add(newSchet);
		return newSchet.getNumber();
	}
	
	private String getFreeAccountNumber() {		
		if(scheta.size() < 1) {
			return Schet.getNextAccountNumber(null);
		}		
		String maxAccountNumber = null;
		for(Schet schet: scheta) {
			if(maxAccountNumber == null) {
				maxAccountNumber = schet.getNumber();
			} else {
				if(schet.compareNumberTo(maxAccountNumber) > 0) {
					maxAccountNumber = schet.getNumber();
				}
			}			
		}
		return Schet.getNextAccountNumber(maxAccountNumber);
	}

    /**
     * Getting a reference to account that is specified by number.
     * Returns null if there is no one.
     * @param number String number of account referent to which you need to obtain.
     */
	public Schet getAccountByNumber(String number) {
        Schet account = null;
		for(Schet schet : scheta) {
			if(schet.getNumber().equals(number)) {
				account = schet;
                break;
			}
		}
        return account;
	}

    /**
     * Deletes specified account. Does nothing if account not found.
     */
	public void closeAccount(String number) {
        Schet account = getAccountByNumber(number);
        if (account != null) {
            scheta.remove(account);
        }
	}

    /**
     * Returns balance on specified account. Or -1 if account not found.
     */
    public double getAccountBalance(String number) {
        Schet account = getAccountByNumber(number);
        double balance = -1;
        if (account != null) {
            balance = getAccountByNumber(number).getBalance();
        }
        return balance;
    }

    /**
     * Returns currency of specified account. if account not found, method will return null.
     */
    public Valuta getAccountCurrency(String number) {
        Schet account = getAccountByNumber(number);
        Valuta valuta = null;
        if (account != null) {
            valuta = getAccountByNumber(number).getValuta();
        }
        return valuta;
    }

    /**
     * Returns a name of this bank.
     */
    public String getName() { return name; }

    /**
     * Returns an unmodifiable set of accounts.
     */
    public Set<Schet> getAccounts() {
        return Collections.unmodifiableSet(scheta);
    }

    @Override
    public int hashCode() {
        int hashCode = 0;
        if (name != null) {
            hashCode += name.hashCode();
        }
        return hashCode;
    }

    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Bank) && name.equals(((Bank)obj).getName());
    }

    @Override
    public String toString() {
        return name;
    }

}